Skip to content

Conversation

@adriencaccia
Copy link
Member

@adriencaccia adriencaccia commented Oct 28, 2025

Fix #86

@codspeed-hq
Copy link

codspeed-hq bot commented Oct 28, 2025

CodSpeed Performance Report

Merging #96 will degrade performances by 24.69%

Comparing feat/remove-cffi (411adc2) with master (adee8a1)

Summary

⚡ 47 improvements
❌ 22 regressions
✅ 98 untouched

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Benchmarks breakdown

Mode Benchmark BASE HEAD Change
Simulation test_iir_filter_process 35.2 µs 32.8 µs +7.29%
WallTime test_iir_filter_process 2.6 µs 2.7 µs -3.85%
Simulation test_iir_filter_set_coefficients[a_coeffs0-b_coeffs0] 16.7 µs 14 µs +19.03%
Simulation test_make_allpass 46.4 µs 43.8 µs +5.99%
Simulation test_make_bandpass 47.1 µs 44.5 µs +5.93%
Simulation test_make_highpass 47.2 µs 44.5 µs +6.13%
Simulation test_make_highshelf 46.1 µs 43.6 µs +5.72%
Simulation test_make_lowpass 47 µs 44.5 µs +5.81%
WallTime test_make_lowpass 5.3 µs 5.5 µs -2.81%
Simulation test_make_lowshelf 46.1 µs 43.6 µs +5.8%
WallTime test_make_lowshelf 7.4 µs 7.2 µs +3.3%
WallTime test_make_peak 6 µs 6.2 µs -2.73%
Simulation test_make_peak 43.3 µs 40.9 µs +5.9%
Simulation test_color[graph0-3] 76.7 µs 74 µs +3.68%
Simulation test_combination_lists[0-0] 26.5 µs 23.9 µs +10.78%
Simulation test_combination_lists[4-2] 31.3 µs 28.7 µs +8.81%
Simulation test_combination_lists[5-4] 31.4 µs 28.9 µs +8.65%
WallTime test_combination_sum[candidates0-8] 10.9 µs 11.1 µs -2.62%
Simulation test_combination_sum[candidates0-8] 43.6 µs 40.9 µs +6.61%
Simulation test_depth_first_search[4] 86.2 µs 84.2 µs +2.34%
... ... ... ... ... ...

ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.

@Vizonex
Copy link

Vizonex commented Oct 29, 2025

Fix #86

This is still a work in progress, it must be tested thoroughly in CI to ensure that it plays well with free-threaded versions of Python, using UV or not.

Sounds good. I can't wait to see if this will pass on through or not.

@adriencaccia
Copy link
Member Author

Sounds good. I can't wait to see if this will pass on through or not.

It seems that there is an issue when running CODSPEED_LOG=debug codspeed --mode instrumentation -- uv run pytest tests/ --codspeed with python3.14t
Here is the error:

Fatal Python error:   ⠠ Running the benchmarks...                                                                                                                                                                                                                                                                      
preconfig_init_allocator:   ⠠ Running the benchmarks...                                                                                                                                                                                                                                                                
PYTHONMALLOC: unknown allocator
Python runtime state:   ⠠ Running the benchmarks...                                                                                                                                                                                                                                                                    
preinitializing  ⠠ Running the benchmarks...                                                                                                                                                                                                                                                                           


Stack (most recent call first):
  <tstate is freed>

In the runner we are setting the following:
https://github.com/CodSpeedHQ/runner/blob/e89b00befed092f3300c89b9f6577a00e025c944/src/run/runner/valgrind/measure.rs#L91

Do you know if there is any issue with free-threaded python and using PYTHONMALLOC?

@Vizonex
Copy link

Vizonex commented Oct 30, 2025

Sounds good. I can't wait to see if this will pass on through or not.

It seems that there is an issue when running CODSPEED_LOG=debug codspeed --mode instrumentation -- uv run pytest tests/ --codspeed with python3.14t Here is the error:

Fatal Python error:   ⠠ Running the benchmarks...                                                                                                                                                                                                                                                                      
preconfig_init_allocator:   ⠠ Running the benchmarks...                                                                                                                                                                                                                                                                
PYTHONMALLOC: unknown allocator
Python runtime state:   ⠠ Running the benchmarks...                                                                                                                                                                                                                                                                    
preinitializing  ⠠ Running the benchmarks...                                                                                                                                                                                                                                                                           


Stack (most recent call first):
  <tstate is freed>

In the runner we are setting the following: https://github.com/CodSpeedHQ/runner/blob/e89b00befed092f3300c89b9f6577a00e025c944/src/run/runner/valgrind/measure.rs#L91

Do you know if there is any issue with free-threaded python and using PYTHONMALLOC?

@adriencaccia Sorry for my rather late response but there is one called PyMem_RawMalloc which can be ran without the gil same with PyMem_RawFree, PyMem_RawRealloc, PyMem_RawCalloc

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates from CFFI-based Python bindings to native CPython extension module to enable free-threaded Python support. The change removes the CFFI dependency and replaces it with a hand-written C extension module that wraps the existing instrument hooks library.

Key changes:

  • Removed CFFI dependency and replaced with native C extension API
  • Added new C module instrument_hooks_module.c implementing Python bindings using CPython's C API
  • Updated InstrumentHooks class to use the new native module instead of CFFI's lib object
  • Modified callgrind function calls to be methods on InstrumentHooks instead of lib properties

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/pytest_codspeed/instruments/valgrind.py Updated callgrind instrumentation calls to use instance methods instead of lib object
src/pytest_codspeed/instruments/hooks/instrument_hooks_module.c New native C extension module implementing Python bindings for instrument hooks
src/pytest_codspeed/instruments/hooks/build.py Removed CFFI build configuration file
src/pytest_codspeed/instruments/hooks/init.py Refactored to use native extension module and added callgrind methods
setup.py Replaced CFFI extension with native Extension setup
pyproject.toml Removed CFFI dependency and updated package data configuration
.github/workflows/ci.yml Added Python 3.14t (free-threaded) to test matrix

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

int32_t pid;
const char *uri;

if (!PyArg_ParseTuple(args, "Oiy", &capsule, &pid, &uri)) {
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The format string 'Oiy' is incorrect. The 'y' format expects const char* with length, but based on the C function signature instrument_hooks_set_executed_benchmark(hooks, pid, uri) which takes const char *uri, this should be 's' for a null-terminated string instead of 'y' which is for bytes with length.

Suggested change
if (!PyArg_ParseTuple(args, "Oiy", &capsule, &pid, &uri)) {
if (!PyArg_ParseTuple(args, "Ois", &capsule, &pid, &uri)) {

Copilot uses AI. Check for mistakes.
const char *name;
const char *version;

if (!PyArg_ParseTuple(args, "Oyy", &capsule, &name, &version)) {
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The format string 'Oyy' is incorrect. Similar to the previous issue, 'y' expects bytes with length. Based on the C function signature which takes const char* parameters, this should be 'Oss' for null-terminated strings.

Suggested change
if (!PyArg_ParseTuple(args, "Oyy", &capsule, &name, &version)) {
if (!PyArg_ParseTuple(args, "Oss", &capsule, &name, &version)) {

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +42
# Don't manually deinit - let the capsule destructor handle it
pass
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The __del__ method with only a pass statement and comment should be removed entirely. An empty __del__ method can prevent proper garbage collection and the capsule destructor will be called automatically without defining __del__.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

python 3.13 on free-threaded mode doesn't work

4 participants